<template>
  <div class="progress-bar" @mousedown="startDrag" ref="progressRef" :style="progressStyle">
    <div class="progress" :style="progressInnerStyle"></div>
    <div class="thumb" :style="thumbStyle"></div>
  </div>
</template>

<script setup>
import { ref, watch, onMounted, onBeforeUnmount, computed } from 'vue'

const props = defineProps({
  max: {
    type: Number,
    default: 100,
  },
})

const emit = defineEmits(['update:value'])

const progressNum = ref(0) // 初始值为 50%
const progressRef = ref(null)
const dragging = ref(false)
const position = ref({ left: 0, progress: 0 })

// 初始化进度条位置
const updateProgress = () => {
  const progressBarWidth = progressRef.value?.offsetWidth ?? 0
  position.value.progress = (progressNum.value / props.max) * progressBarWidth
}

// 拖拽开始
const startDrag = (e) => {
  dragging.value = true
  document.addEventListener('mousemove', onDrag)
  document.addEventListener('mouseup', stopDrag)
  onDrag(e) // 处理点击在滑块上时的情况
}

// 拖拽进行时
const onDrag = (e) => {
  if (!dragging.value || !progressRef.value) return
  const progressBarWidth = progressRef.value.offsetWidth
  const offsetX = e.clientX - progressRef.value.getBoundingClientRect().left
  const progress = Math.min(Math.max(0, offsetX), progressBarWidth)
  position.value.progress = progress
  // 更新值
  const value = (progress / progressBarWidth) * props.max
  emit('update:value', Math.round(value))
}

// 拖拽结束
const stopDrag = () => {
  dragging.value = false
  document.removeEventListener('mousemove', onDrag)
  document.removeEventListener('mouseup', stopDrag)
}

const setProgressNum = (value) => {
  progressNum.value = value
  updateProgress()
}

onMounted(() => {
  updateProgress()
})

onBeforeUnmount(() => {
  document.removeEventListener('mousemove', onDrag)
  document.removeEventListener('mouseup', stopDrag)
})

// 计算样式
const progressInnerStyle = computed(() => ({
  width: `${position.value.progress}px`,
}))

const thumbStyle = computed(() => ({
  left: `${position.value.progress - 10}px`, // Thumb center position
}))

const progressStyle = computed(() => ({
  position: 'relative',
  width: '100%',
  height: '8px',
  backgroundColor: '#ddd',
  borderRadius: '5px',
}))

defineExpose({ setProgressNum })
</script>

<style scoped>
.progress-bar {
  position: relative;
  width: 100%;
  height: 8px;
  background-color: #ddd;
  border-radius: 5px;
  cursor: pointer;
}

.progress {
  height: 100%;
  background-color: #4caf50;
  border-radius: 5px 0 0 5px;
}

.thumb {
  position: absolute;
  top: -4px;
  width: 20px;
  height: 20px;
  background-color: #4caf50;
  border-radius: 50%;
  cursor: pointer;
}
</style>
